package com.wanmait.teatrain.service.impl;

import com.wanmait.teatrain.dto.AdminPaperDTO;
import com.wanmait.teatrain.entity.*;
import com.wanmait.teatrain.mapper.*;
import com.wanmait.teatrain.dto.utils.AIScoreResult;
import com.wanmait.teatrain.service.PaperQuestionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wanmait.teatrain.utils.AjaxResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 考试-试卷与题目关联表 服务实现类
 * </p>
 *
 * @author wanmait
 * @since 2025-10-22
 */
@Service
@Transactional
public class PaperQuestionServiceImpl extends ServiceImpl<PaperQuestionMapper, PaperQuestion> implements PaperQuestionService {
    @Resource
    private PaperQuestionMapper paperQuestionMapper;
    @Resource
    private AdminPaperMapper adminPaperMapper;
    @Resource
    private QuestionsMapper questionsMapper;
    @Resource
    private PaperSetMapper paperSetMapper;
    @Resource
    private OptionsMapper optionsMapper;
    @Resource
    private AIScoringService zhipuAIScoringService;
    /**
     * 提交试卷
     * @param adminPaperDTO
     * 用户提交试卷之后，根据用户答案和题目答案判断是否正确，计算得分
     * 1.adminPaper需要自动添加结束时间
     * 2.paperQuestions中有问题id，用户的答案,
     * 3.从questions表中判断问题类型
     *  3.1.类型为1，选择题，将用户的答案转为integer类型,并于options表中查询is_correct字段,如果为1，则为正确，
     *  3.2.类型为2，判断题，将用户的答案转为Boolean类型,并于questions表中查询judge_answer字段,如果相同，则为正确，
     *  3.3.类型为3，简答题，将用户的答案与question表中的标准答案short_answer和关键词keywords(数据库中每个词以逗号“,”分隔)进行语义匹配，判断是否正确，
     *  3.4.根据上面是否正确，将结果填入paper_question表的is_correct字段，
     *  3.5.根据is_correct字段和paper_set表中对应的问题类型的分数计算得分，填入score字段
     * 4.根据paper_question表中的score字段计算总得分，填入admin_paper表的total_score字段
     * 5.根据admin_paper表中的total_score字段和paper_set表中对应的通过分数pass_score判断是否通过，填入is_pass字段
     * @return
     * 6.返回admin_paper表中的is_pass字段，判断是否通过
     * 7.返回admin_paper表中的total_score用户的总分数
     */
    @Override
    public AjaxResult submit(AdminPaperDTO adminPaperDTO) {
        AdminPaper adminPaper = adminPaperDTO.getAdminPaper();
        List<PaperQuestion> paperQuestions = adminPaperDTO.getPaperQuestions();
        //1.自动添加结束时间
        adminPaper.setEndTime(new Date());
        adminPaperMapper.updateById(adminPaper);

        Integer paperSetId = adminPaper.getPaperSetId();
        PaperSet paperSet = paperSetMapper.selectById(paperSetId);
        //2.遍历paperQuestions,判断问题类型,并根据类型判断是否正确,计算得分
        for (PaperQuestion paperQuestion : paperQuestions) {
            //2.1.根据问题id查询问题类型
            Integer questionId = paperQuestion.getQuestionId();
            Questions questions = questionsMapper.selectById(questionId);
            String questionType = String.valueOf(questions.getQuestionType());
            //2.2.根据问题类型判断是否正确,并计算得分
            if ("1".equals(questionType)) {
                //2.2.1.选择题,将用户的答案转为integer类型,并于options表中查询is_correct字段,如果为1,则为正确
                Integer answer = Integer.parseInt(paperQuestion.getAnswer());
                Options options = optionsMapper.selectById(answer);
                Boolean isCorrect = options.getIsCorrect();
                //  3.4.根据上面是否正确,将结果填入paper_question表的is_correct字段,
                //  3.5.根据is_correct字段和paper_set表中对应的问题类型的分数计算得分,填入score字段
                if (isCorrect) {
                    paperQuestion.setIsCorrect(true);
                    paperQuestion.setScore(paperSet.getSingleChoiceScore());
                } else {

                    
                    paperQuestion.setIsCorrect(false);
                    paperQuestion.setScore(0);
                }
            }
            else if ("2".equals(questionType)) {
                //2.2.2.判断题,将用户的答案转为Boolean类型,并于questions表中查询judge_answer字段,如果相同,则为正确
                Boolean answer = Boolean.parseBoolean(paperQuestion.getAnswer());
                Boolean judgeAnswer = questions.getJudgeAnswer();
                if (answer.equals(judgeAnswer)) {
                    paperQuestion.setIsCorrect(true);
                    paperQuestion.setScore(paperSet.getJudgmentScore());
                } else {
                    paperQuestion.setIsCorrect(false);
                    paperQuestion.setScore(0);
                }
            }
            else if ("3".equals(questionType)) {
                //2.2.3.简答题,将用户的答案与question表中的标准答案short_answer和关键词keywords(数据库中每个词以逗号“,”分隔)进行语义匹配,判断是否正确,
                //获取简答题的满分分数
                Integer shortAnswerScore = paperSet.getShortAnswerScore();
                //  3.4.根据上面是否正确,将结果填入paper_question表的is_correct字段,
                //  3.5.根据is_correct字段和paper_set表中对应的问题类型的分数计算得分,填入score字段
                double questionScore;
                boolean isCorrect;
                String aiFeedback;
                try {
                    AIScoreResult aiResult = zhipuAIScoringService.scoreShortAnswer(
                            paperQuestion.getAnswer(),
                            questions.getShortAnswer(),
                            questions.getKeywords(),
                            shortAnswerScore
                    );

                    questionScore = aiResult.getScore();
                    isCorrect = aiResult.isCorrect();
                    aiFeedback = aiResult.getFeedback();

                    // 保存AI反馈到备注字段
                    paperQuestion.setRemark(aiFeedback);
                    paperQuestion.setScore((int) questionScore);
                    paperQuestion.setIsCorrect(isCorrect);

                } catch (Exception e) {
                    questionScore = 0;
                    isCorrect = false;
                    aiFeedback = "评分服务暂时不可用";
                    // AI评分失败，按0分处理
                    throw new RuntimeException("简答题评分失败，题目ID: " + questionId + ", 错误信息: " + e.getMessage());
                }
            }
            paperQuestionMapper.updateById(paperQuestion);

        }
        //计算总分数
        int totalScore = paperQuestions.stream()
                .mapToInt(PaperQuestion::getScore)
                .sum();
        //将总分数填入admin_paper表的total_score字段
        adminPaper.setTotalScore(totalScore);
        adminPaperMapper.updateById(adminPaper);
        //3.根据total_score字段判断是否及格,并将结果填入is_pass字段
        boolean isPass = totalScore >= paperSet.getPassScore();
        adminPaper.setIsPass(isPass);
        adminPaperMapper.updateById(adminPaper);
        //返回adminPaper
        return AjaxResult.success(adminPaper);
    }
}
